List table
Allow users to easily scan and quickly access key data organized in logical, hierarchical patterns
Examples
Composition:
- Background: A subtle background color can visually separate the list table from surrounding content. Use a neutral color that doesn't compete with the content.
- Item Count (Optional): Display the total number of items in the list, especially for filtered or large datasets. Add context when applicable (e.g., "Filtered by: Active").
- Sorting Indicator (Optional): Clearly indicate the active sorting criteria (e.g., "Sorted by Name (Ascending)"). This helps users understand how the list is organized.
- Rows and Cells (Optional): Rows represent individual data items, while cells hold specific pieces of information within a row.
Basic usage
Use Cases:
- Surface essential information quickly (e.g., site names, scores, policy summaries).
- Offer an overview of data, acting as an entry point to more details. (e.g., Core wins).
- Enable users to scan for patterns and insights.
Best Practices:
- Focus on the most important data points, keeping information density low to avoid overwhelming users.
- Consider embedding list tables within cards or other primary content areas to provide context.
- Keep additional actions (shortcuts, CTAs) to a maximum of two per row to maintain visual clarity.
Dish | Calories | Protein |
|---|---|---|
Beef Stir-Fry | 450 calories | 25 g protein |
Grilled Salmon | 500 calories | 30 g protein |
Veggie Lasagne | 350 calories | 12 g protein |
<ListTable
items={sortItems(items, { property: "dish", direction: "asc" })}
columns={[
{
header: { content: "Dish" },
render: (item) => <div>{item.dish}</div>,
options: { isKeyColumn: true },
},
{ header: { content: "Calories" }, render: (item) => <div>{item.calories}</div> },
{ header: { content: "Protein" }, render: (item) => <div>{item.protein}</div> },
]}
loading={false}
caption="Some table data in a list"
{...translations}
/>Usage with pagination
Use for large datasets. Provide clear controls and indicate the total number of pages. Consider offering options to adjust items per page.
Dish | Calories | Protein |
|---|---|---|
Beef Stir-Fry | 450 calories | 25 g protein |
Grilled Salmon | 500 calories | 30 g protein |
1 - 2 of 3 items
const [page, setPage] = useState(1);
const [pageSize, setPageSize] = useState(2);
const visibleItems = sortItems(items, { property: "dish", direction: "asc" }).slice(
(page - 1) * pageSize,
page * pageSize
);
return (
<ListTable
items={visibleItems}
columns={[
{
header: { content: "Dish" },
render: (item) => <div>{item.dish}</div>,
options: { isKeyColumn: true },
},
{ header: { content: "Calories" }, render: (item) => <div>{item.calories}</div> },
{ header: { content: "Protein" }, render: (item) => <div>{item.protein}</div> },
]}
loading={false}
caption="Some table data in a list"
pagination={{
total: items.length,
count: pageSize,
page: page,
setPage: setPage,
pageSize: pageSize,
setPageSize: setPageSize,
cancelLabel: "Cancel",
confirmLabel: "Confirm",
firstLabel: "First",
prevLabel: "Previous",
nextLabel: "Next",
lastLabel: "Last",
pagingInfoLabel: (startIdx: number, endIdx: number, total: number) =>
`${startIdx} - ${endIdx} of ${total} items`,
pageLabel: "Page",
pageXofYLabel: (current: number, total: number) => `Page ${current} of ${total}`,
pageSizeSelectionLabel: (pageSize: number) => `${pageSize} items`,
pageSizeSelectorPrefix: "Show",
pageSizeSelectorPostfix: "per page",
pageSizeLabel: "Items per page",
defaultError: "Default pagination error",
wholeNumberError: "Must be a whole number",
outOfBoundsError: (total: number) => `Enter a number between 1 and ${total}`,
}}
{...translations}
/>
);Usage with load more buttons
Alternative to pagination when space is limited or the total item count is unknown. Ensure the button is visible and provide loading feedback.
Dish | Calories | Protein |
|---|---|---|
Beef Stir-Fry | 450 calories | 25 g protein |
<ListTable
sort={{ property: "dish", direction: "asc" }}
items={sortItems(items, { property: "dish", direction: "asc" })}
columns={[
{
header: { content: "Dish", property: "dish" },
render: (item) => <div>{item.dish}</div>,
options: { isKeyColumn: true },
},
{ header: { content: "Calories" }, render: (item) => <div>{item.calories}</div> },
{ header: { content: "Protein" }, render: (item) => <div>{item.protein}</div> },
]}
loading={false}
caption="Some table data in a list"
loadMoreCount={1}
showLoadAll
{...translations}
/>Usage with sorting
Allow users to reorder the list. Use a Select for options and indicate the current sorting state.
When using sorted lists, you must provide the sortSelect and sort properties as well as the colums[].header.property value of sortable columns.